package com.xscha.tableforge.service.impl;

import cn.hutool.core.convert.Convert;
import com.xscha.tableforge.constants.FieldType;
import com.xscha.tableforge.model.dto.FieldMetaDto;
import com.xscha.tableforge.model.dto.TableMetaDto;
import com.xscha.tableforge.model.entity.FieldMeta;
import com.xscha.tableforge.model.entity.RelationMeta;
import com.xscha.tableforge.model.entity.TableMeta;
import com.xscha.tableforge.model.vo.PageReq;
import com.xscha.tableforge.model.vo.PageResult;
import com.xscha.tableforge.repository.FieldMetaRepository;
import com.xscha.tableforge.repository.TableMetaRepository;
import com.xscha.tableforge.service.RelationMetaService;
import com.xscha.tableforge.service.TableDataService;
import com.xscha.tableforge.service.FieldMetaService;
import com.xscha.tableforge.utils.EntityFieldUtil;
import com.xscha.tableforge.utils.IdUtil;
import com.xscha.soyue.common.core.utils.BeanMapperUtils;
import lombok.extern.slf4j.Slf4j;
import org.jooq.*;
import org.jooq.impl.SQLDataType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static org.jooq.impl.DSL.*;

/**
 * 动态表服务实现类
 */
@Service
@Slf4j
public class TableDataServiceImpl implements TableDataService {

	private final DSLContext dslContext;
	private final TableMetaRepository tableMetaRepository;
	private final FieldMetaRepository fieldMetaRepository;
	private final RelationMetaService relationMetaService;
	private final FieldMetaService fieldMetaService;

	@Autowired
	public TableDataServiceImpl(DSLContext dslContext,
								TableMetaRepository tableMetaRepository,
								FieldMetaRepository fieldMetaRepository,
								@Lazy RelationMetaService relationMetaService,
								@Lazy FieldMetaService fieldMetaService) { // 添加@Lazy注解
		this.dslContext = dslContext;
		this.tableMetaRepository = tableMetaRepository;
		this.fieldMetaRepository = fieldMetaRepository;
		this.relationMetaService = relationMetaService; // 注入依赖
		this.fieldMetaService = fieldMetaService; // 注入依赖
	}

	@Override
	@Transactional
	public TableMetaDto createTable(TableMetaDto tableMetaDTO, String userId) {
		// 1. 保存表元数据
		TableMeta tableMeta = new TableMeta();
		tableMeta.setId(IdUtil.createDstId());
		tableMeta.setAppId(tableMetaDTO.getAppId());
		tableMeta.setName(tableMetaDTO.getName());
		tableMeta.setDescription(tableMetaDTO.getDescription());
		tableMeta.setIcon(tableMetaDTO.getIcon());
		tableMeta.setDbTableName(tableMeta.getId().toLowerCase());
		tableMeta.setVersion(1);
		tableMeta.setDisplayOrder(tableMetaDTO.getDisplayOrder());
		tableMeta.setCreatedTime(LocalDateTime.now());
		tableMeta.setCreatedBy(userId);

		tableMetaRepository.save(tableMeta);

		// 2. 创建物理表
		createPhysicalTable(tableMeta, tableMetaDTO.getFields());

		// 3. 保存字段元数据
		List<FieldMeta> fieldMetas = saveFieldMetas(tableMetaDTO.getFields(), tableMeta.getId(), userId);

		// 4. 构建返回结果
		TableMetaDto result = new TableMetaDto();
		result.setId(tableMeta.getId());
		result.setAppId(tableMeta.getAppId());
		result.setName(tableMeta.getName());
		result.setDescription(tableMeta.getDescription());
		result.setIcon(tableMeta.getIcon());
		result.setDbTableName(tableMeta.getDbTableName());
		result.setVersion(tableMeta.getVersion());
		result.setDisplayOrder(tableMeta.getDisplayOrder());

		List<FieldMetaDto> fieldMetaDTOs = fieldMetas.stream()
				.map(this::convertToFieldMetaDTO)
				.collect(Collectors.toList());
		result.setFields(fieldMetaDTOs);

		return result;
	}

	/**
	 * 创建物理表
	 */
	private void createPhysicalTable(TableMeta tableMeta, List<FieldMetaDto> fields) {
		// 开始创建表
		var createTableStep = dslContext.createTable(table(tableMeta.getDbTableName()));

		// 添加ID字段（主键）
		createTableStep = createTableStep.column(
				field("id"), SQLDataType.VARCHAR(50).notNull());

		// 添加其他字段
		for (FieldMetaDto field : fields) {
			if (!"id".equalsIgnoreCase(field.getDbFieldName())) {
				DataType<?> dataType = EntityFieldUtil.getJooqDataType(field.getDbFieldType());

				if (field.getNotNull() != null && field.getNotNull()) {
					dataType = dataType.notNull();
				}

				createTableStep = createTableStep.column(
						field(field.getDbFieldName()), dataType);
			}
		}

		// 添加审计字段
		createTableStep = createTableStep
				.column(field("created_time"), SQLDataType.LOCALDATETIME.notNull().defaultValue(currentLocalDateTime()))
				.column(field("created_by"), SQLDataType.VARCHAR(50).notNull())
				.column(field("last_modified_time"), SQLDataType.LOCALDATETIME)
				.column(field("last_modified_by"), SQLDataType.VARCHAR(50))
				.column(field("deleted_time"), SQLDataType.LOCALDATETIME);

		// 执行创建表
		createTableStep.primaryKey(field("id")).execute();
	}

	/**
	 * 保存字段元数据
	 */
	private List<FieldMeta> saveFieldMetas(List<FieldMetaDto> fieldMetaDTOs, String tableId, String userId) {
		List<FieldMeta> result = new ArrayList<>();

		for (FieldMetaDto dto : fieldMetaDTOs) {
			FieldMeta fieldMeta = new FieldMeta();
			BeanMapperUtils.map(dto, fieldMeta);
			fieldMeta.setId(IdUtil.createFieldId());
			fieldMeta.setOptions(EntityFieldUtil.processFieldOptions(dto));
			fieldMeta.setLookupOptions(dto.getLookupOptions());
			fieldMeta.setTableId(tableId);
			fieldMeta.setVersion(1);
			fieldMeta.setCreatedTime(LocalDateTime.now());
			fieldMeta.setCreatedBy(userId);
			fieldMeta.setDisplayOrder(dto.getDisplayOrder());
			fieldMetaRepository.save(fieldMeta);
			result.add(fieldMeta);
		}

		return result;
	}

	/**
	 * 将FieldMeta转换为FieldMetaDTO
	 */
	private FieldMetaDto convertToFieldMetaDTO(FieldMeta fieldMeta) {
		FieldMetaDto dto = new FieldMetaDto();
		BeanMapperUtils.map(fieldMeta, dto);
		dto.setOptions(EntityFieldUtil.convertJsonToOptions(fieldMeta.getOptions()));
		dto.setLookupOptions(fieldMeta.getLookupOptions());
		return dto;
	}

	@Override
	public TableMetaDto getTableMetaWithFields(String tableId) {
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		List<FieldMeta> fieldMetas = fieldMetaRepository.findAllByTableId(tableId);

		TableMetaDto result = new TableMetaDto();
		BeanMapperUtils.map(tableMeta, result);

		List<FieldMetaDto> fieldMetaDTOs = fieldMetas.stream()
				.map(this::convertToFieldMetaDTO)
				.collect(Collectors.toList());
		result.setFields(fieldMetaDTOs);

		return result;
	}

	@Override
	public List<Map<String, Object>> queryData(String tableId, Map<String, Object> conditions) {
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		// 构建查询条件
		Condition whereCondition = field("deleted_time").isNull();
		if (conditions != null && !conditions.isEmpty()) {
			for (Map.Entry<String, Object> entry : conditions.entrySet()) {
				whereCondition = whereCondition.and(field(entry.getKey()).eq(entry.getValue()));
			}
		}

		// 查询数据
		List<Map<String, Object>> records = dslContext.select()
				.from(table(tableMeta.getDbTableName()))
				.where(whereCondition)
				.orderBy(field("created_time").desc())
				.fetchMaps();
				
		// 处理关联字段数据
		List<FieldMeta> fields = fieldMetaRepository.findAllByTableId(tableId);
		return processRelationFields(tableId, records, fields);
	}

	@Override
	public PageResult<Map<String, Object>> queryDataPage(String tableId, Map<String, Object> conditions, PageReq pageRequest) {
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		// 构建查询条件
		Condition whereCondition = field("deleted_time").isNull();
		if (conditions != null && !conditions.isEmpty()) {
			for (Map.Entry<String, Object> entry : conditions.entrySet()) {
				// 排除分页和排序参数
				if (!"pageNum".equals(entry.getKey()) &&
						!"pageSize".equals(entry.getKey()) &&
						!"orderBy".equals(entry.getKey()) &&
						!"orderDirection".equals(entry.getKey())) {

					// 确保字段名使用正确的格式
					String fieldName = EntityFieldUtil.camelToUnderscore(entry.getKey());
					whereCondition = whereCondition.and(field(fieldName).eq(entry.getValue()));
				}
			}
		}

		// 计算总记录数
		int total = dslContext.selectCount()
				.from(table(tableMeta.getDbTableName()))
				.where(whereCondition)
				.fetchOneInto(Integer.class);

		// 如果没有数据，直接返回空结果
		if (total == 0) {
			return PageResult.of(new ArrayList<>(), 0, pageRequest.getPageNum(), pageRequest.getPageSize());
		}

		// 构建排序条件
		List<OrderField<?>> orderFields = new ArrayList<>();
		if (pageRequest.getOrderBy() != null && !pageRequest.getOrderBy().isEmpty()) {
			// 处理字段名，确保使用正确的列名格式（下划线分隔）
			String orderByField = EntityFieldUtil.camelToUnderscore(pageRequest.getOrderBy());
			Field<?> orderField = field(orderByField);
			if ("desc".equalsIgnoreCase(pageRequest.getOrderDirection())) {
				orderFields.add(orderField.desc());
			} else {
				orderFields.add(orderField.asc());
			}
		} else {
			// 默认按创建时间排序
			orderFields.add(field("created_time").desc());
		}

		// 查询分页数据
		List<Map<String, Object>> records = dslContext.select()
				.from(table(tableMeta.getDbTableName()))
				.where(whereCondition)
				.orderBy(orderFields)
				.limit(pageRequest.getPageSize())
				.offset((pageRequest.getPageNum() - 1) * pageRequest.getPageSize())
				.fetchMaps();

		// 转换字段名为驼峰格式，以便前端使用
		List<Map<String, Object>> formattedRecords = records.stream()
				.map(record -> {
					Map<String, Object> formattedRecord = new HashMap<>();
					record.forEach((key, value) -> {
						String camelKey = EntityFieldUtil.underscoreToCamel(key);
						formattedRecord.put(camelKey, value);
					});
					return formattedRecord;
				})
				.collect(Collectors.toList());
		
		// 处理关联字段数据
		List<FieldMeta> fields = fieldMetaRepository.findAllByTableId(tableId);
		formattedRecords = processRelationFields(tableId, formattedRecords, fields);

		return PageResult.of(formattedRecords, total, pageRequest.getPageNum(), pageRequest.getPageSize());
	}

	@Override
	@Transactional
	public Map<String, Object> insertData(String tableId, Map<String, Object> data, String userId) {
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		// 获取表的所有字段，用于类型转换
		List<FieldMeta> fields = fieldMetaService.findAllByTableId(tableId);
		
		// 生成ID
		String id = IdUtil.createRecordId();
		data.put("id", id);
		data.put("created_by", userId);
		data.put("created_time", LocalDateTime.now());

		// 处理数据类型转换
		Map<String, Object> convertedData = new HashMap<>(data);
		for (FieldMeta field : fields) {
			String dbFieldName = field.getDbFieldName();
			if (convertedData.containsKey(dbFieldName)) {
				Object value = convertedData.get(dbFieldName);
				if (value != null) {
					// 根据字段类型进行转换
					convertedData.put(dbFieldName, convertFieldValue(value, field.getDbFieldType()));
				}
			}
		}

		// 构建插入语句
		InsertSetStep<?> insertStep = dslContext.insertInto(table(tableMeta.getDbTableName()));
		InsertSetMoreStep<?> moreStep = null;

		for (Map.Entry<String, Object> entry : convertedData.entrySet()) {
			if (moreStep == null) {
				moreStep = insertStep.set(field(entry.getKey()), entry.getValue());
			} else {
				moreStep = moreStep.set(field(entry.getKey()), entry.getValue());
			}
		}

		if (moreStep != null) {
			moreStep.execute();
		}

		// 返回插入的数据
		return dslContext.select().from(table(tableMeta.getDbTableName()))
				.where(field("id").eq(id))
				.fetchOneMap();
	}
	
	/**
	 * 根据字段类型转换字段值
	 */
	private Object convertFieldValue(Object value, String dbFieldType) {
		if (value == null) {
			return null;
		}
		// 统一转换为小写以便比较
		String type = dbFieldType.toLowerCase();
		try {
			switch (type) {
				case "date":
					return Convert.toDate(value);
				case "datetime":
				case "timestamp":
				case "timestamp with time zone":
					return Convert.toLocalDateTime(value);
				case "int":
				case "integer":
					return Convert.toInt(value);
				case "bigint":
					return Convert.toLong(value);
				case "float":
					return Convert.toFloat(value);
				case "double":
					return Convert.toDouble(value);
				case "decimal":
				case "numeric":
					return Convert.toBigDecimal(value);
				case "boolean":
					return Convert.toBool(value);
				default:
					// 如果是字符串类型或其他未明确处理的类型，尝试转为字符串
					if (type.startsWith("varchar") || type.equals("text")) {
						return Convert.toStr(value);
					}
					// 其他类型保持原值
					return value;
			}
		} catch (Exception e) {
			// 转换失败，记录错误并返回原值
			log.error("转换字段值失败: " + value + " 到类型 " + dbFieldType + ": " + e.getMessage());
		}
		
		// 如果没有匹配的转换或转换失败，返回原值
		return value;
	}

	/**
	 * 处理关联字段数据
	 *
	 * @param tableId 表ID
	 * @param records 记录列表
	 * @param fields  字段列表
	 * @return 处理后的记录列表
	 */
	private List<Map<String, Object>> processRelationFields(
			String tableId, List<Map<String, Object>> records, List<FieldMeta> fields) {
		// 1. 筛选出关联字段
		List<FieldMeta> relationFields = fields.stream()
				.filter(field -> {
					FieldType fieldType = FieldType.fromCode(field.getType());
					return fieldType != null && fieldType.isRelation();
				})
				.collect(java.util.stream.Collectors.toList());

		if (relationFields.isEmpty()) {
			return records;
		}

		// 2. 获取所有记录ID
		List<String> recordIds = records.stream()
				.map(record -> record.get("id").toString())
				.collect(java.util.stream.Collectors.toList());

		// 3. 处理每个关联字段
		for (FieldMeta field : relationFields) {
			// 获取关联字段元数据
			String fieldId = field.getId();
			Optional<RelationMeta> relationMetaOpt = relationMetaService.findByFieldId(fieldId);

			if (!relationMetaOpt.isPresent()) {
				continue;
			}

			RelationMeta relationMeta = relationMetaOpt.get();
			String fieldName = field.getName();
			FieldType fieldType = FieldType.fromCode(field.getType());

			// 获取关联数据
			Map<String, List<String>> relationsMap = relationMetaService.getRelatedRecordsMap(fieldId, recordIds);

			// 将关联数据添加到记录中
			for (Map<String, Object> record : records) {
				String recordId = record.get("id").toString();
				List<String> relatedIds = relationsMap.getOrDefault(recordId, java.util.Collections.emptyList());

				// 根据关系类型处理数据
				if (fieldType == FieldType.RELATION_ONE_TO_ONE || fieldType == FieldType.RELATION_MANY_TO_ONE) {
					// 一对一或多对一关系，取第一个关联ID
					record.put(fieldName, relatedIds.isEmpty() ? null : relatedIds.get(0));
				} else {
					// 一对多或多对多关系，保存为ID列表
					record.put(fieldName, relatedIds);
				}
			}
		}

		return records;
	}

	/**
	 * 保存记录
	 */
	@Override
	@Transactional
	public Map<String, Object> saveRecord(String tableId, Map<String, Object> recordData, String userId) {
		// 1. 获取表元数据
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		// 2. 获取表的所有字段
		List<FieldMeta> fields = fieldMetaService.findAllByTableId(tableId);

		// 3. 分离普通字段和关联字段数据
		Map<String, Object> normalFieldData = new HashMap<>();
		Map<String, Object> relationFieldData = new HashMap<>();

		for (FieldMeta field : fields) {
			String fieldName = field.getName();
			String dbFieldName = field.getDbFieldName();
			
			// 检查记录中是否包含该字段（使用字段名、数据库字段名或其他格式）
			Object value = null;
			if (recordData.containsKey(fieldName)) {
				value = recordData.get(fieldName);
			} else if (recordData.containsKey(dbFieldName)) {
				value = recordData.get(dbFieldName);
			} else if (recordData.containsKey(EntityFieldUtil.camelToUnderscore(fieldName))) {
				// 检查下划线格式
				value = recordData.get(EntityFieldUtil.camelToUnderscore(fieldName));
			} else if (recordData.containsKey(EntityFieldUtil.underscoreToCamel(dbFieldName))) {
				// 检查驼峰格式
				value = recordData.get(EntityFieldUtil.underscoreToCamel(dbFieldName));
			}
			
			// 如果找不到值，继续下一个字段
			if (value == null) {
				continue;
			}

			FieldType fieldType = FieldType.fromCode(field.getType());
			if (fieldType != null && fieldType.isRelation()) {
				relationFieldData.put(field.getId(), value);
			} else {
				normalFieldData.put(dbFieldName, value); // 使用数据库字段名
			}
		}
		
		// 如果normalFieldData为空，记录一下原始数据以便调试
		if (normalFieldData.isEmpty()) {
			System.out.println("警告: normalFieldData为空，原始数据: " + recordData);
		}

		// 4. 保存普通字段数据
		Map<String, Object> savedRecord = saveNormalRecord(tableId, normalFieldData, userId);
		String recordId = savedRecord.get("id").toString();

		// 5. 保存关联字段数据
		for (Map.Entry<String, Object> entry : relationFieldData.entrySet()) {
			String fieldId = entry.getKey();
			Object relationValue = entry.getValue();

			// 获取关联字段元数据
			Optional<RelationMeta> relationMetaOpt = relationMetaService.findByFieldId(fieldId);
			if (!relationMetaOpt.isPresent()) {
				continue;
			}

			RelationMeta relationMeta = relationMetaOpt.get();
			FieldType fieldType = FieldType.fromCode(relationMeta.getRelationType());

			if (fieldType == FieldType.RELATION_ONE_TO_ONE || fieldType == FieldType.RELATION_MANY_TO_ONE) {
				// 一对一或多对一关系
				if (relationValue != null) {
					String targetId = relationValue.toString();
					relationMetaService.createRelation(fieldId, recordId, targetId, userId);
				}
			} else {
				// 一对多或多对多关系
				if (relationValue instanceof List) {
					List<?> targetIds = (List<?>) relationValue;
					List<String> targetIdStrings = targetIds.stream()
							.map(Object::toString)
							.collect(java.util.stream.Collectors.toList());
					relationMetaService.createRelations(fieldId, recordId, targetIdStrings, userId);
				}
			}
		}

		// 6. 返回保存后的记录，包括关联字段数据
		return queryRecordById(tableId, recordId);
	}

	/**
	 * 保存普通字段数据
	 */
	private Map<String, Object> saveNormalRecord(String tableId, Map<String, Object> recordData, String userId) {
		// 获取表的所有字段
		List<FieldMeta> fields = fieldMetaService.findAllByTableId(tableId);
		
		// 准备数据，确保使用正确的字段名（数据库字段名）
		Map<String, Object> dbData = new HashMap<>();
		
		// 检查必填字段并准备数据
		for (FieldMeta field : fields) {
			// 跳过关联字段，它们在另一个步骤中处理
			FieldType fieldType = FieldType.fromCode(field.getType());
			if (fieldType != null && fieldType.isRelation()) {
				continue;
			}
			
			String fieldName = field.getName();
			String dbFieldName = field.getDbFieldName();
			
			// 检查记录中是否包含该字段（使用字段名或数据库字段名）
			Object value = null;
			if (recordData.containsKey(fieldName)) {
				value = recordData.get(fieldName);
			} else if (recordData.containsKey(dbFieldName)) {
				value = recordData.get(dbFieldName);
			}
			
			// 如果是必填字段但值为null，抛出异常
			if (Boolean.TRUE.equals(field.getNotNull()) && value == null) {
				throw new RuntimeException("必填字段 '" + fieldName + "' 不能为空");
			}
			
			// 只有当值不为null时才添加到数据中
			if (value != null) {
				dbData.put(dbFieldName, value);
			}
		}
		
		// 调用插入数据的方法
		return insertData(tableId, dbData, userId);
	}

	/**
	 * 根据ID查询记录
	 */
	public Map<String, Object> queryRecordById(String tableId, String recordId) {
		// 实现这个方法，因为它在代码中被调用但没有实现
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		return dslContext.select()
				.from(table(tableMeta.getDbTableName()))
				.where(field("id").eq(recordId))
				.and(field("deleted_time").isNull())
				.fetchOneMap();
	}

	@Override
	@Transactional
	public Map<String, Object> updateData(String tableId, String recordId, Map<String, Object> data, String userId) {
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		// 添加审计字段
		data.put("last_modified_by", userId);
		data.put("last_modified_time", LocalDateTime.now());

		// 构建更新语句
		UpdateSetStep<?> updateStep = dslContext.update(table(tableMeta.getDbTableName()));
		UpdateSetMoreStep<?> moreStep = null;

		for (Map.Entry<String, Object> entry : data.entrySet()) {
			if (!"id".equals(entry.getKey())) {
				if (moreStep == null) {
					moreStep = updateStep.set(field(entry.getKey()), entry.getValue());
				} else {
					moreStep = moreStep.set(field(entry.getKey()), entry.getValue());
				}
			}
		}

		if (moreStep != null) {
			moreStep.where(field("id").eq(recordId)).execute();
		}

		// 返回更新后的数据
		return dslContext.select().from(table(tableMeta.getDbTableName()))
				.where(field("id").eq(recordId))
				.fetchOneMap();
	}

	@Override
	@Transactional
	public void softDeleteData(String tableId, String recordId, String userId) {
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		dslContext.update(table(tableMeta.getDbTableName()))
				.set(field("deleted_time"), LocalDateTime.now())
				.set(field("last_modified_by"), userId)
				.set(field("last_modified_time"), LocalDateTime.now())
				.where(field("id").eq(recordId))
				.execute();
	}

	@Override
	public Map<String, Object> queryRecordWithRelations(String tableId, String recordId, List<String> includeRelations) {
		// 1. 获取表元数据
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		// 2. 查询基本记录数据
		Map<String, Object> record = queryRecordById(tableId, recordId);
		if (record == null) {
			throw new RuntimeException("记录不存在");
		}

		// 3. 获取表的所有字段
		List<FieldMeta> fields = fieldMetaService.findAllByTableId(tableId);

		// 4. 筛选关联字段
		List<FieldMeta> relationFields = fields.stream()
				.filter(field -> {
					FieldType fieldType = FieldType.fromCode(field.getType());
					return fieldType != null && fieldType.isRelation() &&
							(includeRelations == null || includeRelations.isEmpty() || includeRelations.contains(field.getName()));
				})
				.collect(java.util.stream.Collectors.toList());

		// 5. 处理关联字段数据
		for (FieldMeta field : relationFields) {
			String fieldId = field.getId();
			String fieldName = field.getDbFieldName();

			// 获取关联字段元数据
			Optional<RelationMeta> relationMetaOpt = relationMetaService.findByFieldId(fieldId);
			if (!relationMetaOpt.isPresent()) {
				continue;
			}

			RelationMeta relationMeta = relationMetaOpt.get();
			FieldType fieldType = FieldType.fromCode(field.getType());

			// 根据关系类型处理
			if (fieldType == FieldType.RELATION_ONE_TO_MANY || fieldType == FieldType.RELATION_MANY_TO_MANY) {
				// 对于一对多和多对多关系，需要查询反向关联
				// 获取目标表中引用当前记录的所有记录
				String targetTableId = relationMeta.getTargetTableId();

				// 查询所有关联到当前记录的目标记录
				List<String> relatedIds;

				// 如果是一对多关系，查询所有引用当前记录的目标记录
				if (fieldType == FieldType.RELATION_ONE_TO_MANY) {
					// 查找目标表中引用当前表的字段
					List<FieldMeta> targetTableFields = fieldMetaService.findAllByTableId(targetTableId);
					Optional<FieldMeta> reverseFieldOpt = targetTableFields.stream()
							.filter(f -> {
								FieldType ft = FieldType.fromCode(f.getType());
								return ft == FieldType.RELATION_MANY_TO_ONE &&
										relationMetaService.findByFieldId(f.getId())
												.map(rm -> rm.getTargetTableId().equals(tableId))
												.orElse(false);
							})
							.findFirst();

					if (reverseFieldOpt.isPresent()) {
						FieldMeta reverseField = reverseFieldOpt.get();
						// 查询所有引用当前记录的目标记录
						relatedIds = relationMetaService.getSourceRecordIdsByTargetRecordId(
								reverseField.getId(), recordId);
					} else {
						relatedIds = new ArrayList<>();
					}
				} else {
					// 多对多关系，直接查询关联记录
					relatedIds = relationMetaService.getRelatedRecordIds(fieldId, recordId);
				}

				if (!relatedIds.isEmpty()) {
					// 查询关联记录数据
					List<Map<String, Object>> targetRecords = new ArrayList<>();
					for (String targetRecordId : relatedIds) {
						Map<String, Object> targetRecord = queryRecordById(targetTableId, targetRecordId);
						if (targetRecord != null) {
							targetRecords.add(targetRecord);
						}
					}
					record.put(fieldName, targetRecords);
				} else {
					record.put(fieldName, new ArrayList<>());
				}
			} else {
				// 一对一或多对一关系
				List<String> relatedIds = relationMetaService.getRelatedRecordIds(fieldId, recordId);
				if (!relatedIds.isEmpty()) {
					String targetTableId = relationMeta.getTargetTableId();
					String targetRecordId = relatedIds.get(0);
					Map<String, Object> targetRecord = queryRecordById(targetTableId, targetRecordId);
					record.put(fieldName, targetRecord);
				} else {
					record.put(fieldName, null);
				}
			}
		}

		return record;
	}

	@Override
	public Object queryRelationData(String tableId, String recordId, String fieldName) {
		// 1. 获取表元数据
		TableMeta tableMeta = tableMetaRepository.findById(tableId)
				.orElseThrow(() -> new RuntimeException("表不存在"));

		// 2. 查询基本记录数据
		Map<String, Object> record = queryRecordById(tableId, recordId);
		if (record == null) {
			throw new RuntimeException("记录不存在");
		}

		// 3. 获取字段元数据
		FieldMeta field = fieldMetaService.findAllByTableId(tableId).stream()
				.filter(f -> f.getName().equals(fieldName))
				.findFirst()
				.orElseThrow(() -> new RuntimeException("字段不存在"));

		// 4. 检查是否为关联字段
		FieldType fieldType = FieldType.fromCode(field.getType());
		if (fieldType == null || !fieldType.isRelation()) {
			throw new RuntimeException("不是关联字段");
		}

		// 5. 获取关联字段元数据
		String fieldId = field.getId();
		RelationMeta relationMeta = relationMetaService.findByFieldId(fieldId)
				.orElseThrow(() -> new RuntimeException("关联字段元数据不存在"));

		// 6. 获取关联记录ID
		List<String> relatedIds = relationMetaService.getRelatedRecordIds(fieldId, recordId);
		if (relatedIds.isEmpty()) {
			return fieldType == FieldType.RELATION_ONE_TO_ONE || fieldType == FieldType.RELATION_MANY_TO_ONE ?
					null : new ArrayList<>();
		}

		// 7. 获取关联表元数据
		String targetTableId = relationMeta.getTargetTableId();

		// 8. 查询关联记录数据
		if (fieldType == FieldType.RELATION_ONE_TO_ONE || fieldType == FieldType.RELATION_MANY_TO_ONE) {
			// 一对一或多对一关系，只取第一个关联记录
			String targetRecordId = relatedIds.get(0);
			return queryRecordById(targetTableId, targetRecordId);
		} else {
			// 一对多或多对多关系，获取所有关联记录
			List<Map<String, Object>> targetRecords = new ArrayList<>();
			for (String targetRecordId : relatedIds) {
				Map<String, Object> targetRecord = queryRecordById(targetTableId, targetRecordId);
				if (targetRecord != null) {
					targetRecords.add(targetRecord);
				}
			}
			return targetRecords;
		}
	}

}